package com.weareint.feigncopy;

import com.weareint.common.GsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 *
 *
 * <pre>
 *  使用Redis 实现 AbsCacheMappingFeignDataService
 * </pre>
 *
 * @author johnny
 * @date 2021-08-21 10:24 下午
 */
@Slf4j
public abstract class AbsRedisCacheMappingFeignDataService<S, D, T>
        extends AbsCacheMappingFeignDataService<S, D, T> {

    public static StringRedisTemplate stringRedisTemplate;

    @Override
    public List<D> fromCache(CacheTimeContext timeContext) {
        Set<String> keys = cacheKey();
        List<String> expireKeys = new ArrayList<>();
        List<String> existKeys = new ArrayList<>();
        keys.forEach(
                key ->
                        Optional.ofNullable(stringRedisTemplate.hasKey(key))
                                .ifPresent(
                                        flag -> {
                                            if (!flag) {
                                                expireKeys.add(key);
                                            } else {
                                                existKeys.add(key);
                                            }
                                        }));
        // 过期key 走接口
        List<D> ds =
                cacheFeignData(
                        expireKeys,
                        (key, d) ->
                                stringRedisTemplate
                                        .opsForValue()
                                        .set(
                                                key,
                                                GsonUtils.toJsonStr(d),
                                                timeContext.duration(),
                                                timeContext.timeUnit()));
        List<D> allList = new ArrayList<>(ds);

        // 有效key 走redis
        if (CollectionUtils.isNotEmpty(existKeys)) {
            List<String> existDs = stringRedisTemplate.opsForValue().multiGet(existKeys);
            if (log.isDebugEnabled()) {
                log.debug("【feign mapping redisKeys : {} redisDs：{}】", existKeys, existDs);
            }
            if (CollectionUtils.isNotEmpty(existDs)) {
                existDs.forEach(
                        existJson -> {
                            @SuppressWarnings("unchecked")
                            D o = (D) GsonUtils.fromJsonTo(existJson, context().dClass());
                            allList.add(o);
                        });
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("【feign mapping allList : {}】", allList);
        }
        return allList;
    }
}
